package com.sinodata.bsm.center.web.action.resource;

import java.util.*;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import com.sinodata.bsm.center.bean.ResBean;

import com.sinodata.bsm.center.purview.FunctionConstants;
import com.sinodata.bsm.center.purview.UserFunctionValidate;
import com.sinodata.bsm.center.user.UserUtil;
import com.sinodata.bsm.center.util.web.Struts2Utils;

import com.sinodata.bsm.common.vo.*;
import com.sinodata.bsm.center.web.action.resource.tree.*;

/**
 * 
 * <p>
 * Description: 普通的资源的树
 * </p>
 *
 * @author wangyilin
 * @version 1.0

 * <p>
 * History: 
 *
 * Date                     Author         Version     Description
 * ---------------------------------------------------------------------------------
 * Jan 15, 2013 9:47:31 AM          wangyilin        1.0         To create
 * </p>
 *
 * @since 
 * @see
 */
public class ResTreeAction extends AbstractTreeAction {
    @Override
    protected JSONArray children() throws Exception {
        JSONArray jsonArray = new JSONArray();
        Set<Long> relationTypeIds = resRelationService.getSelfAndSubRelationTypeIds();
        String[] idArray = this.id.split("[|]");
        if (idArray[0].equals(String.valueOf(TreeConstants.NODE_TYPE_RESGROUP))) {
            //没有可能是resgroup
        } else {
            JSONArray children = loadChildNode(Long.parseLong(idArray[1]), relationTypeIds);
            NodeCompare.sortChildNodeSequence(this.id, children);
            jsonArray = children;
        }

        return jsonArray;
    }

    @Override
    protected JSONArray root() throws Exception {
        JSONArray jsonArray = new JSONArray();
        Set<Long> relationTypeIds = resRelationService.getSelfAndSubRelationTypeIds();
        Map<Long, List<ResGroup>> tmpMap = new LinkedHashMap<Long, List<ResGroup>>();
        List<ResGroup> groups = resGroupCache.findByResViewId(this.viewId);
        List<ResGroup> rootResGroup = new ArrayList<ResGroup>();
        if (groups == null) {
            groups = new ArrayList<ResGroup>(0);
        }
        for (ResGroup g : groups) {
            if (g.getParentId() != null) {
                List<ResGroup> arr = tmpMap.get(g.getParentId().longValue());
                if (arr == null) {
                    arr = new ArrayList<ResGroup>();
                    tmpMap.put(g.getParentId().longValue(), arr);
                }
                arr.add(g);
            } else {
                rootResGroup.add(g);
            }
        }

        List<String> nodeTrace = NodePrivilegeUtil.findResNodeTrace(request, this.getViewId());
        for (ResGroup g : rootResGroup) {
            JSONObject gjson = genResGroupNode2(g, tmpMap, relationTypeIds, nodeTrace);
            jsonArray.add(gjson);
        }

        List<Long> rootList = new ArrayList<Long>();
        String userId = UserUtil.getInstance().getCurrentUserId();

        if (UserUtil.getInstance().isSysAdmin(userId)) {
            List<ResViewRel> viewRelList = resViewService.getResViewRelByViewId(viewId);
            if (viewRelList != null) {
                for (ResViewRel rel : viewRelList) {
                    rootList.add(rel.getResId().longValue());
                }
            }
        } else {
            // 不是
            List<Long> resList = UserFunctionValidate.getResIdListForUser(FunctionConstants.VIEW_RES);
            rootList = resViewService.findChildByViewId(viewId, resList);
        }
        Res res = null;

        for (Long rootId : rootList) {

            if ((res = resService.get(rootId)) != null) {
                JSONObject rootJson = genResNode(res, 0L, relationTypeIds);
                if (nodeTrace.contains(rootJson.getString("id"))) {
                    loadResNodeTrace(rootJson, nodeTrace, relationTypeIds);
                }
                jsonArray.add(rootJson);
            }

        }
        return jsonArray;
    }

    /**
     * 刷新树节点
     * @return
     */
    public String refreshTreeNode() {
        Map<String, Integer[]> map = NodePrivilegeUtil.getStatusCache(request, this.viewId);
        Set<Map.Entry<String, Integer[]>> values = map.entrySet();
        List<String[]> statusList = new ArrayList<String[]>();
        List<String[]> resList = new ArrayList<String[]>();
        Set<Long> relationTypeIds = resRelationService.getSelfAndSubRelationTypeIds();

        Map<String, Integer[]> oldResGroups = new HashMap<String, Integer[]>();
        List<ResGroup> rootResGroup = new ArrayList<ResGroup>();
        Map<Long, List<ResGroup>> tmpMap = new HashMap<Long, List<ResGroup>>();
        for (Map.Entry<String, Integer[]> entry : values) {
            String[] nodeIds = entry.getKey().split("[|]");
            int oldStatus = entry.getValue()[0];
            int oldResNum = entry.getValue()[1];
            if (nodeIds[0].equals("2")) {
                //资源节点
                Res res = resService.get(Long.parseLong(nodeIds[1]));
                if (res == null) {
                    continue;
                }
                int currentStatus = res.getPaused() == 1 ? 0 : res.getHealthStatus();
                if (currentStatus != oldStatus) {
                    statusList.add(new String[] { entry.getKey(), "res" + currentStatus });
                    map.put(entry.getKey(), new Integer[] { currentStatus, 0 });
                }
            } else if (nodeIds[0].equals("3")) {
                //资源类别节点
                List<ResBean> children = resService.findChildren(Long.parseLong(nodeIds[2]), Long.parseLong(nodeIds[1]));
                int tmpStatus = 0;
                int pausedSize = 0;
                for (int i = 0; i < children.size(); i++) {
                    Res cRes = children.get(i).res();
                    if (cRes.getHealthStatus() > tmpStatus) {
                        tmpStatus = cRes.getHealthStatus();
                    }
                    if (cRes.getPaused() == 1) {
                        pausedSize++;
                    }
                }
                int currentStatus = children.size() == pausedSize ? 0 : tmpStatus;
                if (oldStatus != currentStatus) {
                    Object[] objs = new Object[2];
                    objs[0] = entry.getKey();
                    objs[1] = "type" + currentStatus;
                    statusList.add(new String[] { entry.getKey(), "type" + currentStatus });
                    map.put(entry.getKey(), new Integer[] { currentStatus, 0 });
                }
            } else if (nodeIds[0].equals("5")) {
                //资源组
                oldResGroups.put(entry.getKey(), entry.getValue());
                Long groupId = Long.parseLong(nodeIds[1]);
                ResGroup group = resGroupCache.get(groupId);
                List<ResGroup> groups = resGroupCache.findByResId(group.getResId());
                for (ResGroup g : groups) {
                    if (g.getParentId() != null) {
                        List<ResGroup> arr = tmpMap.get(g.getParentId().longValue());
                        if (arr == null) {
                            arr = new ArrayList<ResGroup>();
                            tmpMap.put(g.getParentId().longValue(), arr);
                        }
                        arr.add(g);
                    } else {
                        rootResGroup.add(g);
                    }
                }

            }

        }
        for (ResGroup g : rootResGroup) {
            refreshResGroupNode(g, tmpMap, relationTypeIds, statusList, resList, oldResGroups);
        }

        Struts2Utils.renderJson(new List[] { statusList, resList });
        return null;
    }

    private Integer[] refreshResGroupNode(ResGroup g, Map<Long, List<ResGroup>> childMap, Set<Long> relationTypesIds, List<String[]> statusList, List<String[]> resList, Map<String, Integer[]> oldResGroups) {
        long pid = g.getParentId() == null ? 0 : g.getParentId();
        String nodeId = TreeConstants.NODE_TYPE_RESGROUP + "|" + g.getId() + "|" + pid;
        List<MotiResRel> relList = motiResRelCache.findByResGroupId(g.getId());
        int num = 0;
        int maxStatus = 1;
        if (childMap.containsKey(g.getId().longValue())) {
            List<ResGroup> children = childMap.get(g.getId().longValue());
            for (ResGroup child : children) {
                Integer[] childJson = refreshResGroupNode(child, childMap, relationTypesIds, statusList, resList, oldResGroups);
                num += childJson[1];
                if (maxStatus < childJson[0]) {
                    maxStatus = childJson[0];
                }

            }
        }
        if (relList != null) {
            for (MotiResRel rel : relList) {
                Res res = null;
                if ((res = resService.get(rel.getResId())) != null && NodePrivilegeUtil.hasResViewPrivilege(res.getId(), relationTypesIds, request)) {
                    if (maxStatus < res.getHealthStatus()) {
                        maxStatus = res.getHealthStatus();
                    }
                    num++;
                }
            }
        }
        if (oldResGroups.containsKey(nodeId)) {
            Integer[] olds = oldResGroups.get(nodeId);
            if (olds[0] != maxStatus) {
                statusList.add(new String[] { nodeId, "type" + maxStatus });
            }
            if (num != olds[1]) {
                resList.add(new String[] { nodeId, g.getName() + "(" + num + ")" });
            }
        }
        Integer[] newVal = new Integer[] { maxStatus, num };
        NodePrivilegeUtil.getStatusCache(request, this.viewId).put(nodeId, newVal);
        return newVal;
    }

}
